import './Process.scss';
import React, { RefObject, useRef } from 'react';
import gsap from 'gsap';
import { animateObj, animationBaseProps } from '../Animation';
import { createLabel } from '../utils/animationTools';

let dealDuration:(num: number) => any = (duration: number) => {
  const baseSlice = 12;
  const baseDuration = duration;
  return (length: number) => (baseDuration * length) / baseSlice;
};

const Process: React.FC<animationBaseProps<null>> = (props) => {
  const processRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const barRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const backRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const floorRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const roofRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const frontRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
  const frontFontRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);

  React.useEffect(() => {
    dealDuration = dealDuration(props.animateObj.duration);
    createProcessGsap(
      props.animateObj.t1,
      props.animateObj,
      processRef.current,
      barRef.current,
      {
        backRef: backRef.current,
        floorRef: floorRef.current,
        roofRef: roofRef.current,
        frontRef: frontRef.current,
        frontFontRef: frontFontRef.current
      }
    );
    return function cleanup() {
      console.log('组件被卸载componentWillUnmount');
    };
  }, []);

  return <div className={'process-box'} ref={processRef}>
    <div className='bar' ref={barRef}>
      <div className='bar-face back' ref={backRef}>
        <div className={'percentage'}/>
      </div>
      <div className='bar-face floor' ref={floorRef}>
        <div className={'percentage'}/>
      </div>
      <div className='bar-face roof' ref={roofRef}>
        <div className={'percentage'}/>
      </div>
      <div className='bar-face front' ref={frontRef}>
        <span className={'font f-center'} ref={frontFontRef}>LOADING</span>
        <svg width='50' height='50' className={'f-center'}>
          <polyline fill='none' stroke='#f2f2f2' strokeWidth='3' points='11,27 21,30 38,17'
            strokeLinecap='round' strokeLinejoin='round' className='tick'/>
        </svg>
        <div className={'percentage'}/>
      </div>
    </div>
  </div>;
};

function createProcessGsap(
  t1: GSAPTimeline,
  animateObj: animateObj<null>,
  boxTarget: HTMLDivElement|null,
  barTarget: HTMLDivElement|null,
  barFaceTarget: {
    backRef: HTMLDivElement|null,
    floorRef: HTMLDivElement|null,
    roofRef: HTMLDivElement|null,
    frontRef: HTMLDivElement|null,
    frontFontRef: HTMLDivElement|null,
  }
) {
  // 进度条高度
  t1.add([
    gsap.to(boxTarget, {
      duration: dealDuration(1),
      height: 5,
      opacity: 1
    })
  ], animateObj.position);

  // 进度条宽度
  t1.add([
    gsap.to(boxTarget, {
      duration: dealDuration(1),
      width: 500,
      right: 0
    })
  ], animateObj.position + '+=' + dealDuration(1));

  // 进度条开始
  t1.add(
    [
      gsap.to('.percentage', {
        duration: dealDuration(8),
        width: 500,
        ease: 'sine.in'
      })
    ],
    animateObj.position + '+=' + dealDuration(2)
  );

  // 宽度增加
  t1.to(boxTarget, {
    duration: dealDuration(1),
    height: 50,
    top: 0
  }, animateObj.position + '+=' + dealDuration(3));

  // 变身3d
  t1.to(barTarget, {
    duration: dealDuration(1),
    rotateX: 55,
    transformStyle: () => 'preserve-3d'
    // height: 10
  }, animateObj.position + '+=' + dealDuration(4));

  // 3d立体
  t1.add([
    gsap.to(barFaceTarget.roofRef, {
      duration: dealDuration(2),
      translateZ: 50
    }),
    gsap.fromTo(barFaceTarget.backRef, {
      height: 0,
      top: 50
    }, {
      duration: dealDuration(2),
      height: 50,
      top: 0
    }),
    gsap.fromTo(barFaceTarget.frontRef, {
      height: 0,
      top: 50
    }, {
      duration: dealDuration(2),
      height: 50,
      top: 0
    })
  ],
  animateObj.position + '+=' + dealDuration(5));

  // 完成加载动画
  t1.add([
    gsap.to(barFaceTarget.frontFontRef, {
      duration: dealDuration(1),
      letterSpacing: '-12px',
      opacity: 0
    }),
    gsap.fromTo('.tick', {
      strokeDasharray: 40,
      strokeDashoffset: 40
    }, {
      duration: dealDuration(2),
      strokeDashoffset: 0
    })
  ], animateObj.position + '+=' + dealDuration(10));

  createLabel(t1, animateObj);
  // 回调
  animateObj.callAnimate && animateObj.callAnimate(barTarget, t1);
}

export default Process;
